import { AppCTX } from "../../types/koaExtend";
import { createBrandApiMWRouter } from "../../middleware/brand-api/brandAdminChecker";
import {
  isNumber,
  isBoolean,
  isArray,
  _pick,
  isUndefined,
  StringIndexer,
  isInteger,
} from "mmb";
import pageMW from "../../middleware/pager";
import { Brand } from "../../service/declareTypes";
import {
  getBrandWithExtAndStat,
  updateBrand,
  upsertBrandEndorsement,
  upsertBrandDistributeEndorsement,
  upsertBrandDistributeSupplySetting,
  upsertBrandDistributeProduct,
  batchUpsertBrandDistributeProducts,
  listBrandProductWithDistributeInfos,
  getBrandEndorsementByBrandIDSafely,
  getBrandDistributeEndorsementByBrandIDSafely,
  getBrandDistributeSupplySettingByBrandIDSafely,
  getBrandSettlementAccountInfo,
  createBrandAccountWithdrawApplyment,
  listBrandAccountWithdrawApplyments,
  listBrandAccountLogs,
  aggrBrandAccountLogsToInOut,
} from "../../service/brandService";
import {
  getLatestBrandBankCardByBrandID,
  upsertBrandBankCard,
} from "../../service/brandBankCardService";
import { listSearchObjectsAsBrand } from "../../service/commonService";
import UserStratification, {
  isUserStratification,
} from "../../bg-enums/userStratification";
import { everyIsBrandEndorseApplyField } from "../../bg-enums/brandEndorseApplyField";
import { isSearchTerm } from "../../bg-enums/searchTerm";
import DeliveryMode, { isDeliveryMode } from "../../bg-enums/deliveryMode";
const router = createBrandApiMWRouter();

//获取品牌信息 适用于:星团首页
router.get("/brd/:brandId/brand", async (ctx: AppCTX, next) => {
  // const { userId } = ctx;
  const { brandId } = ctx.params;
  const { page } = ctx.query;
  const brandWithExtAndStat = await getBrandWithExtAndStat(brandId);

  let body = {
    ..._pick(
      brandWithExtAndStat,
      "brandId",
      "name",
      "intro",
      "pic",
      "homepageBg",
      "tel",
      "fansCount",
      // "adminCount",
      // "spokesmanCount",
      "publishActivityCount",
      "endorseRequestToAuditCount",
      "ownUserId",
      "isWxpayAvailable",
      "isDuringApplication"
    ),
  };
  if (page === "brand-index") {
    let availableAmount = 0,
      pendingAmount = 0,
      withdrawedAmount = 0;
    if (body.isWxpayAvailable) {
      const brandSettlementAccountInfo = await getBrandSettlementAccountInfo(
        brandId
      );
      availableAmount = brandSettlementAccountInfo.availableAmount;
      pendingAmount = brandSettlementAccountInfo.pendingAmount;
      withdrawedAmount = brandSettlementAccountInfo.withdrawedAmount;
    }
    body.earningStats = {
      availableAmount,
      pendingAmount,
      withdrawedAmount,
    };
  }
  ctx.body = body;
});

// 更新品牌信息
router.put("/brd/:brandId/brand/update", async (ctx: AppCTX, next) => {
  // const { userId } = ctx;
  const { brandId } = ctx.params;
  const { intro, pic, homepageBg, tel } = ctx.request.body;
  let brand: Brand | undefined = undefined;
  // 不允许更新品牌名称
  // if (!isUndefined(name)) {
  //   // 获取name
  //   brand = await getBrand(brandId)
  //   if (name !== brand.name) {
  //     // 更新到webpos_brand
  //   }
  // }
  brand = await updateBrand({ brandId, intro, pic, homepageBg, tel });
  const output = _pick(brand, "name", "intro", "pic", "homepageBg", "tel");

  ctx.body = {
    ...output,
  };
});

// // 更新品牌某一属性
// router.put(
//   "/brd/:brandId/brand/updateOneProperty",
//   async (ctx: AppCTX, next) => {
//     const { userId } = ctx;
//     const { brandId } = ctx.params;
//     const { key, value } = ctx.request.body;
//     const keysForUpdate = ["homepageBackground", "pic", "name", "servicePhone"];
//     if (!keysForUpdate.includes(key)) {
//       ctx.throw(400, "update key is invalid");
//     }
//     // const brand = await UpdateBrand({brandId, name})
//     // key is one of 'homepageBackground, pic, name, servicePhone'
//     ctx.body = {
//       brandId,
//       userId,
//       key,
//       value,
//     };
//   }
// );

// //  获取品牌的配送费信息
// router.get("/brd/:brandId/brand/getShippingFee", async (ctx: AppCTX, next) => {
//   const { userId } = ctx;
//   const { brandId } = ctx.params;

//   ctx.body = {
//     brandId,
//     userId,
//     isShippingFeeFromRule: false,
//     unifiedShippingFee: 600,
//   };
// });

// // 设置品牌的配送费
// router.put("/brd/:brandId/brand/setShippingFee", async (ctx: AppCTX, next) => {
//   const { userId } = ctx;
//   const { brandId } = ctx.params;
//   const { isShippingFeeFromRule, unifiedShippingFee } = ctx.request.body;

//   if (!isBoolean(isShippingFeeFromRule)) {
//     ctx.throw(400, "is_shipping_fee_from_rule is invalid");
//   }
//   if (
//     !isShippingFeeFromRule &&
//     (!isNumber(unifiedShippingFee) || unifiedShippingFee < 0)
//   ) {
//     ctx.throw(400, "unified_shipping_fee is invalid");
//   }
//   ctx.body = {
//     brandId,
//     userId,
//     isShippingFeeFromRule,
//     unifiedShippingFee,
//   };
// });

// 获取品牌的代言信息
router.get("/brd/:brandId/brand/endorsement", async (ctx: AppCTX, next) => {
  const { userId } = ctx;
  const { brandId } = ctx.params;

  const brandEndorsement = await getBrandEndorsementByBrandIDSafely(brandId);
  ctx.body = {
    ..._pick(
      brandEndorsement,
      "brandId",
      "isOpen",
      "spokesmanTitle",
      "userStratified",
      "consumerLowerExpense",
      "needApplyInfo",
      "applyInfoFields",
      "isEntranceDisplay",
      "isAutoApproved"
    ),
  };
});

// 设置品牌的代言信息
router.put("/brd/:brandId/brand/endorsement", async (ctx: AppCTX, next) => {
  const { userId } = ctx;
  const { brandId } = ctx.params;
  const {
    isOpen,
    spokesmanTitle,
    userStratified,
    needApplyInfo,
    isEntranceDisplay,
    isAutoApproved,
  } = ctx.request.body;
  let { consumerLowerExpense, applyInfoFields } = ctx.request.body;

  // chdck field releation
  if (!isUserStratification(userStratified)) {
    ctx.throw("400", "userStratified is invalid");
  } else {
    if (userStratified === UserStratification.ANYONE) {
      consumerLowerExpense = undefined;
    } else {
      if (!isInteger(consumerLowerExpense)) {
        ctx.throw("400", "consumerLowerExpense is invalid");
      }
    }
  }

  if (needApplyInfo) {
    if (!everyIsBrandEndorseApplyField(applyInfoFields)) {
      ctx.throw("400", "applyInfoFields is invalid");
    }
  } else {
    applyInfoFields = undefined;
  }

  const brandEndorsement = await upsertBrandEndorsement({
    brandId,
    isOpen,
    spokesmanTitle,
    userStratified,
    consumerLowerExpense,
    needApplyInfo,
    applyInfoFields,
    isEntranceDisplay,
    isAutoApproved,
  });

  ctx.body = {
    ..._pick(
      brandEndorsement,
      "brandId",
      "isOpen",
      "spokesmanTitle",
      "userStratified",
      "consumerLowerExpense",
      "needApplyInfo",
      "applyInfoFields",
      "isEntranceDisplay",
      "isAutoApproved"
    ),
  };
});

// 获取品牌的分销招募信息
router.get(
  "/brd/:brandId/brand/distributeEndorsement",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;

    const brandDistributeEndorsement =
      await getBrandDistributeEndorsementByBrandIDSafely(brandId);
    ctx.body = {
      ...brandDistributeEndorsement,
    };
  }
);

// 设置品牌的分销招募信息
router.put(
  "/brd/:brandId/brand/distributeEndorsement",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    const {
      isOpen,
      distributorTitle,
      userStratified,
      needApplyInfo,
      isEntranceDisplay,
      isAutoApproved,
    } = ctx.request.body;
    let { consumerLowerExpense, applyInfoFields } = ctx.request.body;

    // chdck field releation
    if (!isUserStratification(userStratified)) {
      ctx.throw("400", "userStratified is invalid");
    } else {
      if (userStratified === UserStratification.ANYONE) {
        consumerLowerExpense = undefined;
      } else {
        if (!isInteger(consumerLowerExpense)) {
          ctx.throw("400", "consumerLowerExpense is invalid");
        }
      }
    }

    if (needApplyInfo) {
      if (!everyIsBrandEndorseApplyField(applyInfoFields)) {
        ctx.throw("400", "applyInfoFields is invalid");
      }
    } else {
      applyInfoFields = undefined;
    }

    const brandDistributeEndorsement = await upsertBrandDistributeEndorsement({
      brandId,
      isOpen,
      distributorTitle,
      userStratified,
      consumerLowerExpense,
      needApplyInfo,
      applyInfoFields,
      isEntranceDisplay,
      isAutoApproved,
    });

    ctx.body = {
      ...brandDistributeEndorsement,
    };
  }
);

// 获取品牌分销的供货设置
router.get(
  "/brd/:brandId/brand/distributeSupplySetting",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;

    const brandDistributeSupplySetting =
      await getBrandDistributeSupplySettingByBrandIDSafely(brandId);
    ctx.body = {
      ...brandDistributeSupplySetting,
    };
  }
);

// 设置品牌分销的供货设置
router.put(
  "/brd/:brandId/brand/distributeSupplySetting",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    const {
      deliveryModes,
      isUseWarehouseShippingFeeRule,
      unifiedShippingFee,
      warehouseIds,
    } = ctx.request.body;
    if (!isUndefined(deliveryModes)) {
      if (
        !isArray(deliveryModes) ||
        deliveryModes.length === 0 ||
        deliveryModes.some((mode) => !isDeliveryMode(mode))
      ) {
        throw Error("deliveryModes invalid");
      }

      if (deliveryModes.some((mode) => mode === DeliveryMode.IN_CITY)) {
        throw Error("deliveryMode in_city not imp");
      }
    } else {
      throw Error("deliveryModes empty");
    }

    if (!isUndefined(unifiedShippingFee) && !isNumber(unifiedShippingFee)) {
      throw Error("unifiedShippingFee invalid");
    }

    if (
      isUndefined(warehouseIds) ||
      !isArray(warehouseIds) ||
      warehouseIds.length === 0
    ) {
      throw Error("warehouseIds not set or empty");
    }

    const brandDistributeSupplySetting =
      await upsertBrandDistributeSupplySetting({
        brandId,
        deliveryModes,
        isUseWarehouseShippingFeeRule,
        unifiedShippingFee,
        warehouseIds,
      });

    ctx.body = {
      ...brandDistributeSupplySetting,
    };
  }
);

// 列出品牌供货商品列表
router.get(
  "/brd/:brandId/brand/distributeProducts",
  pageMW,
  async (ctx: AppCTX, next) => {
    const { brandId } = ctx.params;
    let { productGroupId, keyword } = ctx.query;
    const { userId, limit, offset, ts } = ctx;

    const { total, items } = await listBrandProductWithDistributeInfos(
      { brandId, productGroupId, keyword },
      {
        limit,
        offset,
        ts,
      }
    );

    ctx.body = {
      total,
      rows: items,
    };
  }
);

// 设置单条品牌供货商品
router.put(
  "/brd/:brandId/brand/distributeProduct",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    const { productId } = ctx.request.body;
    let { percentOff } = ctx.request.body;

    if (isUndefined(percentOff)) {
      percentOff = 0;
    } else {
      if (!isNumber(percentOff)) {
        throw Error("percentOff invalid");
      }
    }

    const brandDistributeSupplySetting = await upsertBrandDistributeProduct({
      brandId,
      productId,
      percentSale: 1000,
      percentOff: Number(percentOff),
    });

    ctx.body = {
      ...brandDistributeSupplySetting,
    };
  }
);

// 批量设置品牌供货商品
router.put(
  "/brd/:brandId/brand/distributeProducts",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    let { percentOff } = ctx.request.body;

    if (isUndefined(percentOff)) {
      percentOff = 0;
    } else {
      if (!isNumber(percentOff)) {
        throw Error("percentOff invalid");
      }
    }

    const success = await batchUpsertBrandDistributeProducts({
      brandId,
      percentSale: 1000,
      percentOff: Number(percentOff),
    });

    ctx.body = {};
  }
);

// 获取品牌的提现银行卡
router.get("/brd/:brandId/brand/bankCard", async (ctx: AppCTX, next) => {
  const { userId } = ctx;
  const { brandId } = ctx.params;

  const brandBankCard = await getLatestBrandBankCardByBrandID(brandId);
  if (isUndefined(brandBankCard)) {
    ctx.throw(404, "NOT_FOUND");
  }
  ctx.body = {
    ..._pick(
      brandBankCard,
      "brandBankCardId",
      "accountType",
      "accountBank",
      "bankAddressCode",
      "bankName",
      "accountNumber",
      "verifyResult"
    ),
  };
});

// 设置品牌的提现银行卡
router.put("/brd/:brandId/brand/bankCard", async (ctx: AppCTX, next) => {
  const { userId } = ctx;
  const { brandId } = ctx.params;
  const { accountType, accountBank, bankAddressCode, bankName, accountNumber } =
    ctx.request.body;

  const brandBankCard = await upsertBrandBankCard({
    brandId,
    userId,
    accountType,
    accountBank,
    bankAddressCode,
    bankName,
    accountNumber,
  });

  ctx.body = {
    ..._pick(
      brandBankCard,
      "brandBankCardId",
      "accountType",
      "accountBank",
      "bankAddressCode",
      "bankName",
      "accountNumber",
      "verifyResult"
    ),
  };
});

// 获取品牌的结算账户信息
router.get(
  "/brd/:brandId/brand/settlementAccountInfo",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;

    const brandSettlementAccountInfo = await getBrandSettlementAccountInfo(
      brandId
    );
    ctx.body = brandSettlementAccountInfo;
  }
);

// 商家申请提现
router.post(
  "/brd/:brandId/brand/accountWithdrawApplyment",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    const { amount, remark } = ctx.request.body;

    const brandAmountWithdrawApplyment =
      await createBrandAccountWithdrawApplyment({
        brandId,
        userId,
        amount,
        remark,
      });

    ctx.body = brandAmountWithdrawApplyment;
  }
);

// 获取品牌的提现记录列表
router.get(
  "/brd/:brandId/brand/accountWithdrawApplyments",
  pageMW,
  async (ctx: AppCTX, next) => {
    const { brandId } = ctx.params;
    const { userId, limit, offset } = ctx;
    const { total, items } = await listBrandAccountWithdrawApplyments(brandId, {
      limit,
      offset,
    });
    ctx.body = {
      total,
      rows: items,
    };
  }
);

// 获取品牌的资金明细列表
router.get(
  "/brd/:brandId/brand/accountLogs",
  pageMW,
  async (ctx: AppCTX, next) => {
    const { brandId } = ctx.params;
    const { userId, limit, offset } = ctx;
    const { total, items } = await listBrandAccountLogs(brandId, {
      limit,
      offset,
    });
    ctx.body = {
      total,
      rows: items,
    };
  }
);

// 统计品牌的资金收入与支出
router.get(
  "/brd/:brandId/brand/aggrBrandAccountLogsToInOut",
  async (ctx: AppCTX, next) => {
    const { userId } = ctx;
    const { brandId } = ctx.params;
    const { begin, end } = ctx.request.query;

    const aggrRet = await aggrBrandAccountLogsToInOut(brandId, {
      begin: isUndefined(begin) ? 0 : parseInt(begin),
      end: isUndefined(end) ? Date.now() : parseInt(end),
    });

    ctx.body = aggrRet;
  }
);

// 获取品牌使用的查询对象列表
router.get(
  "/brd/:brandId/brand/searchObjects",
  pageMW,
  async (ctx: AppCTX, next) => {
    const { brandId } = ctx.params;
    const { term, keyword } = ctx.query;
    const { userId, limit, offset } = ctx;

    if (!isSearchTerm(term)) {
      ctx.throw(400, "term invalid");
    }

    const { total, items } = await listSearchObjectsAsBrand(
      brandId,
      term,
      keyword,
      {
        limit,
        offset,
      }
    );
    ctx.body = {
      total,
      rows: items,
    };
  }
);

export default router;
